package sql2struct

import (
	"fmt"
	"os"
	"strings"
	"text/template"

	"gitee.com/hlwqds/go-project/CLiTool/cobra/internal/word"
)

const structTp1 = `type {{.TableName | ToCamelCase}} struct {
{{range .Columns}}  
	{{ $length := len .Comment}} 
	{{ if gt $length 0 }}//{{.Comment}} {{else}}// {{.Name}} {{end}}
	{{$typeLen := len .Type}} 
	{{if gt $typeLen 0}}{{.Name | ToCamelCase}} {{.Type}} {{.Tag}}{{else}}{{.Name}}{{end}}
{{end}}
	
func (model {{.TableName | ToCamelCase}}) TableName() string{
	return "{{.TableName}}"
}`

type StructTemplate struct {
	structTp1 string
}

type StructColumn struct {
	Name    string
	Type    string
	Tag     string
	Comment string
}

type StructTemplateDb struct {
	TableName string
	Columns   []*StructColumn
}

func NewStructTemplate() *StructTemplate {
	return &StructTemplate{structTp1: structTp1}
}

func (t *StructTemplate) AssemblyColumns(tbColumns []*TableColumn) []*StructColumn {
	tp1Columns := make([]*StructColumn, 0, len(tbColumns))
	for _, column := range tbColumns {
		tag := fmt.Sprintf("`"+"json:"+"\"%s\""+"`", column.ColumnName)
		column.ColumnType = strings.Split(column.ColumnType, "(")[0]
		fmt.Println(column.ColumnType)
		tp1Columns = append(tp1Columns, &StructColumn{
			Name:    column.ColumnName,
			Type:    DBTypeToStructType[column.ColumnType],
			Tag:     tag,
			Comment: column.ColumnComment,
		})
	}
	return tp1Columns
}

func (t *StructTemplate) Generate(tableName string, tp1Columns []*StructColumn) error {
	tp1 := template.Must(template.New("sql2struct").Funcs(template.FuncMap{
		"ToCamelCase": word.UnderscoreToUpperCamelCase,
	}).Parse(t.structTp1))
	tp1DB := StructTemplateDb{
		TableName: tableName,
		Columns:   tp1Columns,
	}
	err := tp1.Execute(os.Stdout, tp1DB)
	if err != nil {
		return err
	}
	return nil
}
